use crate::util::from_slice_with_null_to_str;
use core::ptr::copy;

#[repr(C)]
pub struct PersisParams {
    pub device_uid: [u8; 64],
    pub product_code: [u8; 64],
    pub device_sn: [u8; 64],
    pub secret: [u8; 64],
    pub activate_secret: [u8; 64],
    pub servers: [Server; 6],
}

#[repr(C)]
pub struct Server {
    pub ip: [u8; 32],
    pub domain: [u8; 32],
    pub server_type: u8,
    pub proto_type: u8,
}

impl Server {
    pub fn ip_str(&self) -> &str {
        from_slice_with_null_to_str(self.ip.as_slice())
    }

    pub fn domain_str(&self) -> &str {
        from_slice_with_null_to_str(self.domain.as_slice())
    }
}

impl PersisParams {
    pub fn get() -> &'static mut Self {
        unsafe {
            if PARAMS.is_none() {
                Self::load()
            }
            PARAMS.as_mut().unwrap()
        }
    }

    fn load() {
        unsafe {
            let mut params: PersisParams = core::mem::zeroed();
            copy(
                "ePro-VF2901".as_ptr(),
                params.product_code.as_mut_ptr(),
                "ePro-VF2901".len(),
            );
            copy(
                "EPROS014I3M9NYBVK0017E7716".as_ptr(),
                params.device_uid.as_mut_ptr(),
                "EPROS014I3M9NYBVK0017E7716".len(),
            );
            copy(
                "87oortdj4tb83e92zuqy4u717hqgcg04".as_ptr(),
                params.secret.as_mut_ptr(),
                "87oortdj4tb83e92zuqy4u717hqgcg04".len(),
            );
            copy(
                "123456".as_ptr(),
                params.device_sn.as_mut_ptr(),
                "123456".len(),
            );
            PARAMS = Some(params)
        }
    }

    pub fn save() {}

    pub fn product_code_str(&self) -> &str {
        from_slice_with_null_to_str(self.product_code.as_slice())
    }

    pub fn device_uid_str(&self) -> &str {
        from_slice_with_null_to_str(self.device_uid.as_slice())
    }

    pub fn secret_str(&self) -> &str {
        from_slice_with_null_to_str(self.secret.as_slice())
    }

    pub fn activate_secret_str(&self) -> &str {
        from_slice_with_null_to_str(self.activate_secret.as_slice())
    }
}

static mut PARAMS: Option<PersisParams> = None;
